<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/2/28
 * Time: 11:45
 */

namespace lib;
class CSV
{
    public $error = [
        "msg"=>'',
        "data"=>null,
    ];
    public $separator = ',';
    public function __construct()
    {

    }

    /**
     * 抛出错误
     * @param $msg
     * @param null $data
     * @throws \Exception
     */
    public function error($msg, $data = null)
    {
        $this->error = array_merge($this->error, [
            "msg"=>$msg,
            "data"=>$data,
        ]);
        throw new \Exception($msg);
    }


    /**
     * 获取CSV文件数据
     * @param $file
     * @param string $func
     * @param int $mode
     * @return array|bool
     */
    public function getData($file, $func = "",$mode = 1)
    {
        //文件不存在
        if(!file_exists($file)){
            $this->error('File is not exists.');
            return false;
        }
        //处理函数不存在
        if(!is_object($func) && !function_exists($func)){
            $this->error('Handle function is not exists.');
            return false;
        }

        $tmp = file_get_contents($file);
        $rowStr = count(explode("\r\n", $tmp)) > 1 ? explode("\r\n", $tmp) : explode("\n", $tmp);

        $keys = null;
        if($mode == 1){
            $keys = array_values(explode($this->separator, $rowStr[0]));
            $row = 1;
        } else {
            $row = 0;
        }
        $percent = 0;
        $whithOutSqlTime = 0;
        $sqlTime = 0;
        $start = microtime(true);
        for($i = $row; $i < count($rowStr) - 1; $i++) {
            $data = [];
            $tmp = [];
            if($rowStr[$i]){
                $data = $this->getRowData($rowStr[$i]);
            }
            if(isset($data) && is_array($data)){
                foreach($data as $key => $val){
                    if($keys[$key]){
                        $tmp[$keys[$key]] = trim(htmlspecialchars_decode($val));
                    } else{
                        $tmp[] = trim(htmlspecialchars_decode($val));
                    }
                }
            }

            if(floor($i / count($rowStr) * 100) > $percent){
                $percent = floor($i / count($rowStr) * 100);
                $scriptTime = microtime(true) - $start;
                $whithOutSqlTime = $scriptTime - $sqlTime;
                echo date('Y-m-d H:i:s').':'.$percent."%.\n";
                echo "Script time: {$scriptTime}  sql time: {$sqlTime} with out sql time: {$whithOutSqlTime} \n";
//                if($percent > 10){
//                    exit;
//                }
            }
            if($tmp){
                $res = $func($tmp, $i + 1, count($rowStr), $sqlTime);
                if($res !== true && $res !== 1){
                    $this->error($res, $tmp);
                    return $res;
                }
            }
        }

        return true;
    }

    public function getRowData($rowStr = '')
    {
        $rowStr = mb_convert_encoding($rowStr, 'UTF-8', 'ASCII,GB2312,GBK,BIG5');
        $result = [];
        while(($position = strpos($rowStr, $this->separator)) !== false){
            if(strpos($rowStr, '"') === 0){
                $position = strpos($rowStr, '"'.$this->separator) + 1;
            }
            $result[] = trim($position != 0 ? substr($rowStr, 0, $position) : '',  '"');
            $rowStr = substr($rowStr, $position + 1);
        }
        if($rowStr){
            $result[] = $rowStr;
        }
        return $result;
    }


    /**
     * 保存到文件
     * @param array $data
     * @param string $file
     * @param null $path
     * @return bool
     */
    public function toFile($data = [], $file = '', $path = null)
    {
        if(!$data){
            return false;
        }
        if(!is_dir($path)){
            $res = mkdir($path);
        }
        if(!$file){
            do{
                $file = time().rand(1000, 9999).'.csv';
                $file = $path ? $path.'/'.$file : $file;
            }while(file_exists($file));
        }

        if($path && !file_exists($file)){
            touch($file);
        }
        $str_tmp = [];
        foreach($data as $item){
            $item = array_map(function($val){
                return preg_match('/^\d+$/', $val) ? $val : '"'.iconv('utf-8', 'gbk', $val).'"';
            }, $item);
            $str_tmp[] = join(',', $item);
        }
        $result_str = join("\r\n", $str_tmp);
        if($path){
            if(!file_exists($file)){
                touch($file);
            }
            file_put_contents($file, $result_str);
        } else {
            $this->download($file, $result_str);
        }
    }

    /**
     * 下载
     * @param $file
     * @param $content
     */
    public function download($file, $content)
    {
        header("Content-type:text/csv");
        header("Content-Disposition:attachment;filename=".$file);
        header('Cache-Control:must-revalidate,post-check=0,pre-check=0');
        header('Expires:0');
        header('Pragma:public');
        echo $content;
    }

}
